<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style type="text/css">
        #a {
            border: 1px solid black;
        }
    </style>

</head>
<body>
<canvas id="a" width="900" height="1900">
</canvas>
<script>
    var canvas = document.getElementById('a');
    var context = canvas.getContext('2d');

    var items = [
        {text: 'Item named political 1', point: 90},
        {text: 'Item 2', point: 90},
        {text: 'Item name  3', point: 90},
        {text: 'Item Item Item 4', point: 75},
        {text: 'Item 0', point: 61},
        {text: 'Item Item Item 115', point: 61},
        {text: 'Item 33', point: 33},
        {text: 'Item 5', point: 10},
        {text: 'Test item number 6', point: 10},
        {text: 'Test item number 7.1', point: 5},
        {text: 'Test item number 7.2', point: 5},
        {text: 'Test item number 7.3', point: 5}
    ];

    var items1 = [
        {text: 'Item named political 1', point: 90},
        {text: 'Item name  3', point: 90},
        {text: 'Item Item Item 4', point: 75},
        {text: 'Item 0', point: 61},
        {text: 'Item Item Item 115', point: 61},
        {text: 'Item 33', point: 33},
        {text: 'Item 5', point: 10}

    ];


    var items3 = [
        {text: 'Item named political 1', point: 90},
        {text: 'Item 2', point: 80},
        {text: 'Item name  3', point: 80},
        {text: 'Item Item Item 4', point: 75},
        {text: 'Item 0', point: 61},
        {text: 'Item 5', point: 50},
        {text: 'Test item number 6', point: 10},
        {text: 'Test number 7.1', point: 33},
        {text: 'Test item number 123.2', point: 33},
        {text: 'Test item number', point: 5}
    ];


    var items4 = [
        {text: 'Item named political 1', point: 90},
        {text: 'Item 2', point: 80},
        {text: 'Item name  3', point: 80},
        {text: 'Item Item Item 4', point: 75},
        {text: 'Item 0', point: 61},
        {text: 'Item 5', point: 50},
        {text: 'Test item number 6', point: 10},
        {text: 'Test number 7.1', point: 33},
        {text: 'Test item number 123.2', point: 33},
        {text: 'Test item number', point: 5}
    ];


    var items5 = [
        {text: 'Item named political 1', point: 90},
        {text: 'Item 2', point: 80},
        {text: 'Item name  3', point: 80},
        {text: 'Item Item Item 4', point: 75}

    ];

    var first = drawCategory(items, context, 40, 10);
    var next = drawCategory(items1, context, 20, first.next_y +20);
    first = boundCategory(context, first, next);
    next = drawCategory(items3, context, 20, next.next_y + 20);
    first = boundCategory(context, first, next);
    next = drawCategory(items4, context, 20, next.next_y + 20);
    first = boundCategory(context, first, next);
    next = drawCategory(items5, context, 20, next.next_y + 20);
    first = boundCategory(context, first, next);

    function boundCategory(context, c1, c2){
        var x_start;

        var el = {};

        el.max_y = (c1.y > c2.y) ? c1: c2;
        el.min_y = (c1.y < c2.y) ? c1: c2;

        el.max_x = (c1.x > c2.x) ? c1: c2;
        el.min_x = (c1.x < c2.x) ? c1: c2;

        context.moveTo(el.min_x.x, el.min_x.y);
        context.lineTo(el.max_x.x, el.min_x.y);

        context.moveTo(el.max_x.x, el.min_x.y);
        context.lineTo(el.max_x.x, el.max_x.y);

        var middle =(el.max_y.y+el.min_y.y)/2;

        context.moveTo(el.max_x.x, middle);
        context.lineTo(el.max_x.x + 25, middle);

        context.stroke();

        return {x: el.max_x.x + 25, y: middle};
    }

    function drawCategory(items, context, start_x, start_y) {

        var y_line_h = 22;
        var max_text_width = getMaxMeasureText(items);
        var start_x = (start_x) ? start_x : 20;
        var start_y = (start_y) ? start_y : 20;
        var start_pos_x = start_x + max_text_width;
        var start_pos_y = start_y;
        var len_line = 25;
        var coef = 10;
        var union = [];
        var lastLine;


        context.beginPath();

        drawItemText(items);

        start_pos_x = start_pos_x + 5;

        for (var i = 0; i < items.length; i++) {

            if (union.length > 0) {
                if (union[0].point != items[i].point) {
                    lastLine = drawUnion(union);
                    union = [];
                    union.lastLine = lastLine;
                }
            }

            union.push({y_start: start_pos_y +  (i + 1) * y_line_h, point: items[i].point});

            if (i == items.length - 1) {
                lastLine = drawUnion(union);
                union = [];
                union.lastLine = lastLine;
            }

        }

        context.stroke();
        context.closePath();

        return lastLine;

        function drawItemText(items) {
            context.font = "13px Arial";
            for (var i = 1; i < items.length + 1; i++) {

                context.fillText(items[i - 1].text, start_pos_x, start_pos_y + i * y_line_h);
            }
        }

        function getMaxMeasureText(items) {
            var max = 0;

            for (var i = 0; i < items.length; i++) {
                context.textAlign = 'right';
                var width = context.measureText(items[i].text).width;
                if (max < width)
                    max = width;
            }
            return max;
        }

        function drawUnion(union) {

            var middle_x_start = 0;
            var middle_y_start = 0;

            for (var i = 0; i < union.length; i++) {
                var line_xl;
                if (!union.lastLine) {
                    line_xl = start_pos_x + (100 - union[i].point) / 10 + coef + len_line;
                } else {
                    line_xl = union.lastLine.x
                }

                //draw line from items
                context.moveTo(start_pos_x, union[i].y_start - 5);
                context.lineTo(line_xl, union[i].y_start - 5);

                if (i == union.length - 1) {
                    var y_pos = union[0].y_start - 5;

                    // form las element draw line which unite line in group
                    context.moveTo(line_xl, union[i].y_start - 5);
                    context.lineTo(line_xl, y_pos);

                    middle_x_start = line_xl;
                }

                middle_y_start += union[i].y_start - 5
            }

            middle_y_start = Math.floor(middle_y_start / union.length);

            var current_x = middle_x_start + len_line;

            //draw line from the center of union block
            context.moveTo(middle_x_start, middle_y_start);
            context.lineTo(current_x, middle_y_start);

            var result_x = middle_x_start + len_line;
            var result_y = middle_y_start;

            if (union.lastLine) {
                var last_x = union.lastLine.x;
                var last_y = union.lastLine.y;

                //for next union block bound it with previous and draw middle line

                context.moveTo(last_x, last_y);
                context.lineTo(current_x, last_y);

                context.moveTo(current_x, last_y);
                context.lineTo(current_x, middle_y_start);

                result_y = (middle_y_start + last_y) / 2;
                result_x = current_x + len_line;

                context.moveTo(current_x, result_y);
                context.lineTo(result_x, result_y);
            }

            return {x: result_x, y: result_y, next_y: union[union.length-1].y_start};
        }
    }


</script>
</body>
</html>